home *** CD-ROM | disk | FTP | other *** search
Modula Implementation | 1996-09-27 | 7.3 KB | 271 lines |
- IMPLEMENTATION MODULE DuTypefile;
-
- (*$S-*)(*$T-*)(*$A+*)
-
- (*
- Written by Greg Browne from ideas in duIII.c - many thanks to
- Chris Nicotra, Dave Jobusch, Ed Alford, and many others whose
- names I have not seen on the source files who have worked on
- the development and extension of that fine directory utility program.
-
- PURPOSE A self-contained, IMPORTable pair of procedures to allow
- a screen display - or printer copy - in Hex or ASCII of
- any disk files.
-
- CHANGES 1/24/87 Built original.
-
- *)
-
- FROM SYSTEM IMPORT ADR;
- FROM Strings IMPORT String,InitStringModule,Concat,Assign;
- FROM DOSFiles IMPORT FileHandle,ModeOldFile,ModeNewFile,Close,
- Open,Read,Write,Lock,Unlock,AccessRead,
- FileLock;
- FROM DOSLibrary IMPORT DOSName,DOSBase;
- FROM Libraries IMPORT OpenLibrary,CloseLibrary;
-
- (*COMMENTS*)
-
- (* This module tries to open the DOSLibrary for use in case it is not open.
- IT DOES NOT CLOSE IT. The user is left with that chore. *)
-
- (* All constants and variables are internal. Nothing but PROCEDURES
- are available to the user. *)
-
- CONST
- lf = 12C;
- dot = ".";
- cr = 15C;
- expl = "q[33m<CR>q[2m = next line - q[33m<SPACE>q[2m = next page - q[33m<ESC>q[2m = abortq[0m";
- wipe = "x x";
- last ="q[33mEnd of File. Press SPACE q[0m";
-
- VAR
- HexCh : ARRAY [0..16] OF CHAR;
- Disk,
- Display : FileHandle;
- fp1,fp2,
- fp3,fp4 : CARDINAL;
- c : CHAR;
- len,len2,
- i,
- top,
- linecount,
- nextout : CARDINAL;
- Result : LONGINT;
- DiskERR,
- PastEOF,
- KeepWaiting,
- OnScreen,
- Quit : BOOLEAN;
- command : ARRAY[0..79] OF CHAR;
- writebuffer : ARRAY[0..80] OF CHAR;
- t2 : ARRAY[1..20] OF CHAR;
- inbuffer : ARRAY[0..512] OF CHAR;
-
-
- (* INTERNAL PROCEDURES - NOT IN .def FILE AND NOT IMPORTABLE *)
-
-
- PROCEDURE MyOpen(VAR ufn:ARRAY OF CHAR):BOOLEAN;
- VAR i:CARDINAL;lk:FileLock;
- BEGIN
- linecount := 0;
- Disk := 0;
- Quit := FALSE;
- lk := Lock(ufn,AccessRead);
- IF (lk <> 0) THEN
- Unlock(lk);
- Disk := Open(ufn,ModeOldFile);
- END;
- IF Disk = 0 THEN
- RETURN FALSE
- ELSE
- IF OnScreen THEN
- Concat("RAW:0/0/640/200/Listing of: ",ufn,command);
- ELSE
- command := "PRT:"
- END;
- Display := Open(command,ModeNewFile);
- IF Display = 0 THEN
- Close(Disk); (* if here - Disk is open *)
- RETURN FALSE
- ELSE
- Quit := FALSE;
- RETURN TRUE
- END
- END
- END MyOpen;
-
- (* write a string to 'f' - faster than multiple WriteChar's *)
-
- PROCEDURE WriteString(f:FileHandle;VAR s:ARRAY OF CHAR);
- VAR i:CARDINAL;
- BEGIN
- i := 0;
- WHILE (i<=HIGH(s)) AND (s[i]<>0C) DO INC(i) END;
- Result := Write(f,ADR(s),LONGCARD(i));
- END WriteString;
-
- (* read (with wait) single character from 'f' (here it is keyboard) *)
-
- PROCEDURE ReadChar(f:FileHandle;VAR c:CHAR);
- BEGIN
- Result := Read(f,ADR(c),1);
- IF Result < 1 THEN c := 0C END
- END ReadChar;
-
- (* Press Space message and wait for continue-nextline-cancel *)
-
- PROCEDURE Pause;
- BEGIN
- IF OnScreen THEN
- linecount := 1;
- WriteString(Display,expl);
- KeepWaiting := TRUE;
- REPEAT
- ReadChar(Display,c);
- IF c = CHR(27) THEN
- Quit := TRUE;
- ELSIF c = CHR(13) THEN
- linecount := 21;
- END
- UNTIL (Quit) OR (c = 15C) OR (c = 40C);
- WriteString(Display,wipe);
- END;
- END Pause;
-
- (* End - press space message & wait for space *)
-
- PROCEDURE Finish;
- BEGIN
- IF OnScreen THEN
- WriteString(Display,last);
- REPEAT ReadChar(Display,c) UNTIL (c = 40C);
- END;
- END Finish;
-
- (* Closes the disk file and screen (or printer) - NOT DOS Library *)
-
- PROCEDURE CloseTheFile;
- BEGIN
- IF (Display <> 0) THEN Close(Display) END;
- IF (Disk <> 0) THEN Close(Disk) END;
- END CloseTheFile;
-
- (* internal procedure for the HexDisplay *)
- (* Converts a character to a 3 byte (null terminated 3d byte) string *)
- (* in hex format with leading '0' *)
-
- PROCEDURE ToHex(c:CHAR;VAR ch:ARRAY OF CHAR);
- VAR v:CARDINAL;
- BEGIN
- v := CARDINAL(ORD(c));
- ch[0] := HexCh[v DIV 16];
- ch[1] := HexCh[v MOD 16];
- ch[2] := 0C;
- END ToHex;
-
- (* kludge to quickly convert a 4 byte (artificial LONGCARD) thingy into
- an increasing file position - used 4 byte since very big files should
- really be taken into account - as if anyone is going to dump a file
- that long - oh, well, it will address it properly if they do *)
-
- PROCEDURE HexAddr(VAR ch:ARRAY OF CHAR);
- VAR re:ARRAY[0..2] OF CHAR;
- BEGIN
- IF fp1=256 THEN fp1 := 0; INC(fp2) END; (* with any other *)
- IF fp2=256 THEN fp2 := 0; INC(fp3) END; (* necessary movement *)
- IF fp3=256 THEN fp3 := 0; INC(fp4) END;
- IF fp4=256 THEN fp4 := 0 END; (*if THAT big, just roll*)
- ToHex(CHR(fp4),re);
- ch[0] := re[0];ch[1] := re[1];
- ToHex(CHR(fp3),re);
- ch[2] := re[0];ch[3] := re[1];
- ToHex(CHR(fp2),re);
- ch[4] := re[0];ch[5] := re[1];
- ToHex(CHR(fp1),re);
- ch[6] := re[0];ch[7] := re[1];
- INC(fp1,16);
- END HexAddr;
-
- (* FINALLY THE FIRST IMPORTABLE PROCEDURE *)
- (* SET ToScreen FALSE to go to PRT: device *)
-
- PROCEDURE DisplayASCII(VAR filnam:ARRAY OF CHAR;ToScreen:BOOLEAN);
- BEGIN
- OnScreen := ToScreen;
- IF MyOpen(filnam) THEN
- REPEAT
- len := CARDINAL(Read(Disk,ADR(inbuffer),512));
- len2 := 0;
- WHILE (NOT Quit) AND (len2 < len) DO
- i := len2;
- WHILE (i < 511) AND (inbuffer[i] <> 12C) DO INC(i) END;
- Result := Write(Display,ADR(inbuffer[len2]),LONGCARD(i-len2+1));
- len2 := i + 1;
- INC(linecount);
- IF (linecount > 21) AND (inbuffer[i] = 12C) THEN Pause END;
- END;
- UNTIL (len <> 512) OR (Quit);
- Finish;
- END; (* IF NOT Quit *)
- CloseTheFile;
- END DisplayASCII;
-
-
- PROCEDURE DisplayHex(VAR filnam:ARRAY OF CHAR;ToScreen:BOOLEAN);
- VAR ad:ARRAY[0..7] OF CHAR;
- BEGIN
- OnScreen := ToScreen;
- IF MyOpen(filnam) THEN
- fp1:=0;fp2:=0;fp3:=0;fp4:=0;
- REPEAT
- FOR i := 0 TO 70 DO writebuffer[i] := 40C END;
- top := CARDINAL(Read(Disk,ADR(t2),16));
- nextout := 10;
- IF top > 0 THEN
- FOR i := 1 TO top DO
- ToHex(t2[i],ad);
- writebuffer[nextout] := ad[0];
- writebuffer[nextout+1] := ad[1];
- INC(nextout,2);
- IF (i MOD 4)=0 THEN INC(nextout) END;
- END;
- nextout := 48; (* 39 IF i MOD 8 is left in *)
- FOR i := 1 TO top DO
- IF (t2[i]>177C) OR (t2[i]<40C) THEN
- writebuffer[nextout] := dot
- ELSE
- writebuffer[nextout] := t2[i]
- END;
- INC(nextout);
- END;
- writebuffer[69] := lf;
- writebuffer[70] := 0C;
- HexAddr(ad);
- FOR i := 0 TO 7 DO writebuffer[i] := ad[i] END;
- Result := Write(Display,ADR(writebuffer),70);
- INC(linecount);
- IF (linecount > 21) THEN Pause END;
- END;
- UNTIL (top < 16) OR (Quit);
- Finish
- END;
- CloseTheFile
- END DisplayHex;
-
-
- (* Initialization items *)
-
-
- BEGIN
- IF DOSBase = 0 THEN DOSBase := OpenLibrary(DOSName,0) END;
- IF DOSBase = 0 THEN HALT END; (* WHOOPS!!*)
-
- InitStringModule;
-
- HexCh := "0123456789ABCDEF";
-
- END DuTypefile.
-